/**
 * Copyright (c) Daniel Centore
 *
 * ex: set filetype=java expandtab tabstop=4 shiftwidth=4 :
 *
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 *
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * This code is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation.
 */
package ronp.anim.data;

import java.awt.Point;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;

/**
 * Represents a single grip which can be moved
 * 
 * @author Daniel Centore
 *
 */
public class Grip implements Serializable
{
	private static final long serialVersionUID = 2L;

	private static int currentGrip = 0; // How many grips there are

	private int uniqueID = currentGrip++; // For testing
	private HashMap<Integer, Point> positions; // A map of its position at different keyframes

	/**
	 * Creates a grip
	 */
	public Grip()
	{
		positions = new HashMap<Integer, Point>();
	}

	/**
	 * Gets the position of this grip at a certain frame
	 * If there is no position in this frame, it retrieves the one before it
	 * @param frame The frame to retrieve it from
	 * @return The position
	 */
	public Point getPosition(int frame)
	{
		int below = -1;
		List<Integer> ord = new ArrayList<Integer>(positions.keySet().size());
		for (Integer i : positions.keySet())
			ord.add(i);
		Collections.sort(ord);

		for (int i : ord)
		{
			if (i > frame)
			{
				return positions.get(below); // returns the earlier one, we have no frame here.
			}
			else if (i == frame)
				return positions.get(i);
			else
				below = i;
		}

		return positions.get(below); // no more frames
	}

	/**
	 * Tests if this grip has a set position in a frame
	 * @param frame The frame to test it on
	 * @return True if it has one; False otherwise
	 */
	public boolean isEmpty(int frame)
	{
		return (positions.get(frame) == null);
	}

	/**
	 * Sets the position of this grip in a certain frame
	 * @param frame The frame to set it in
	 * @param pos The position it is at
	 */
	public void setPosition(int frame, Point pos)
	{
		positions.put(frame, pos);
	}

	/**
	 * Removes a position
	 * @param frame Frame to remove
	 * @throws RuntimeException If we try to remove frame 0
	 */
	public void removePosition(int frame)
	{
		if (frame == 0)
			throw new RuntimeException("Cannot remove position 0!");

		positions.remove(frame);
	}

	/**
	 * @return A {@link Set} of the position entries in the form frame,position
	 */
	public Set<Entry<Integer, Point>> entrySet()
	{
		return positions.entrySet();
	}

	@Override
	public String toString()
	{
		return "Grip [positions=" + positions + ", uniqueID=" + uniqueID + "]";
	}

}
